home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Celestin Apprentice 5
/
Apprentice-Release5.iso
/
Source Code
/
PowerPlant
/
DMultiStringLocator
/
source
/
CSearchWindow.cp
next >
Wrap
Text File
|
1996-07-06
|
8KB
|
261 lines
// ===========================================================================
// CSearchWindow.cp
// ---------------------
// ©1996 Eric Gundrum, All rights reserved.
// The contents of this file may be freely altered and freely distributed
// in any form, provided this copyright statement is retained unaltered.
// Add your own changes below.
// ---------------------
//
// Coordinate activities of the Search Window.
// This is pretty crappy code.
//
// PowerPlant Headers
#include <LFileStream.h>
#include <UDebugging.h>
#include <UException.h>
#include <UReanimator.h>
// Library Headers
// Project Headers
#include "CSearchWindow.h"
// ===========================================================================
#pragma mark --- static CSearchString ---
// ===========================================================================
long CSearchString::mBufferOffset = 0; // static initializer
// ===========================================================================
#pragma mark --- public CSearchWindow ---
// ===========================================================================
// ---------------------------------------------------------------------------
// Constructor
CSearchWindow::CSearchWindow()
{
ShowSearchWindow();
}
// ---------------------------------------------------------------------------
// Request search criteria from the user
void
CSearchWindow::ShowSearchWindow()
{
mSearchWindowP = LWindow::CreateWindow( window_Search, this );
UReanimator::LinkListenerToControls( this, mSearchWindowP, window_Search );
mSearchWindowP -> Show();
}
// ---------------------------------------------------------------------------
//
void
CSearchWindow::ListenToMessage
( MessageT inMessage
, void* ioParam
)
{
switch( inMessage )
{
case msg_FilterExecute:
DoSearch();
break;
case msg_FilterCancel:
LCommander::ObeyCommand(cmd_Quit, ioParam);
// delete mSearchWindowP; // ••• probably not safe
// ••• also should destroy this object, but I don't know how yet
break;
case msg_BroadcasterDied:
mSearchWindowP = nil; // delete is built into LWindow
break;
}
}
// ---------------------------------------------------------------------------
//
void
CSearchWindow::DoSearch()
{
// process the contents of the search window into a CSearchString list
LEditField *theEditFieldP = nil;
theEditFieldP = dynamic_cast<LEditField*>
(mSearchWindowP->FindPaneByID( editField_Target1 ));
InsertSearchItem( 1, *theEditFieldP );
theEditFieldP = dynamic_cast<LEditField*>
(mSearchWindowP->FindPaneByID( editField_Target2 ));
InsertSearchItem( 2, *theEditFieldP );
theEditFieldP = dynamic_cast<LEditField*>
(mSearchWindowP->FindPaneByID( editField_Target3 ));
InsertSearchItem( 3, *theEditFieldP );
// ask for the file to search
StandardFileReply theReply;
::StandardGetFile( nil, -1, nil, &theReply );
if ( true == theReply.sfGood )
{
LFileStream target( theReply.sfFile );
// do the search
long startTime = ::TickCount();
SearchFile( target );
long duration = (::TickCount() - startTime + 30)/60;
// report results
CSearchString *searchItemP = nil;
LCaption *resultsCaptionP = nil;
LStr255 countStr;
mSearchList.FetchItemAt( 1, &searchItemP );
resultsCaptionP = dynamic_cast<LCaption*>(mSearchWindowP->FindPaneByID( caption_Result1 ));
resultsCaptionP -> SetDescriptor( countStr.Assign( searchItemP->GetFoundCount() ) );
mSearchList.FetchItemAt( 2, &searchItemP );
resultsCaptionP = dynamic_cast<LCaption*>(mSearchWindowP->FindPaneByID( caption_Result2 ));
resultsCaptionP -> SetDescriptor( countStr.Assign( searchItemP->GetFoundCount() ) );
mSearchList.FetchItemAt( 3, &searchItemP );
resultsCaptionP = dynamic_cast<LCaption*>(mSearchWindowP->FindPaneByID( caption_Result3 ));
resultsCaptionP -> SetDescriptor( countStr.Assign( searchItemP->GetFoundCount() ) );
resultsCaptionP = dynamic_cast<LCaption*>(mSearchWindowP->FindPaneByID( caption_Duration ));
resultsCaptionP -> SetDescriptor( countStr.Assign( duration ) );
}
EmptySearchList(); // prepare it for the next use
::SysBeep(1);
}
// ---------------------------------------------------------------------------
// Open and read a file, calling a SearchBuffer reapeatedly until the entire
// file is searched.
//
// Backup the stream to correct for partial matches at the end of the buffer.
void
CSearchWindow::SearchFile( LFileStream &inTarget )
{
const int bufferSize = 4096; // should be at least 4096 for efficiency
int bytesRead, partialMatch;
Uchar *bufferP = new Uchar[bufferSize];
EventRecord theEvent;
DMultiStringLocator locator( mSearchList ); // search engine
// validate inputs
ThrowIfNil_( &inTarget );
inTarget.OpenDataFork( fsRdPerm );
while ( !inTarget.AtEnd() ) // for each buffer...
{
// read file data into a buffer
CSearchString::SetBufferOffset( inTarget.GetMarker() );
bytesRead = inTarget.ReadData( bufferP, bufferSize );
if( (bytesRead < bufferSize) && !inTarget.AtEnd() )
{
SignalCStr_("File Read Error Occurred.");
}
partialMatch = locator.SearchBuffer( bufferP, bytesRead );
if ( DMultiStringLocator::searchStatus_stop == partialMatch )
{
inTarget.SetMarker( 0, streamFrom_End );
}
else if ( !inTarget.AtEnd() ) // backup to re-search partial match
{
inTarget.SetMarker( -1*partialMatch, streamFrom_Marker );
}
// give some time back to the system
::EventAvail ( keyDownMask, &theEvent );
}
inTarget.CloseDataFork();
}
// ---------------------------------------------------------------------------
// • AllowSubRemoval
// ---------------------------------------------------------------------------
// This function returns true if a subcommander can be removed as would occur
// from clicking the close box in a window.
//
// This is a convenient place to take settings from the window and save them.
// AttempQuitSelf is a better place.
Boolean
CSearchWindow::AllowSubRemoval( LCommander *inSubP )
{
mSearchWindowP = nil; // ••• until there is code to process the data
if ( inSubP == mSearchWindowP )
{
((LWindow *) inSubP)->Hide();
// process close of window through close box
return false;
}
else
{
return true;
}
}
// ---------------------------------------------------------------------------
// Destructor.
CSearchWindow::~CSearchWindow()
{
}
// ===========================================================================
#pragma mark --- private CSearchWindow ---
// ===========================================================================
// ---------------------------------------------------------------------------
// Place a search item in the list of searchable items.
void
CSearchWindow::InsertSearchItem( Int32 inPos, LEditField &inEditField )
{
CSearchString *theStringP = new CSearchString();
ThrowIfMemFail_( theStringP );
ThrowIfNil_( &inEditField ); // validate input
inEditField.GetDescriptor( *theStringP ); // zero length items are OK
mSearchList.InsertItemsAt( 1, inPos, &theStringP );
}
// ---------------------------------------------------------------------------
// Empty contents of search list.
void
CSearchWindow::EmptySearchList()
{
// destroy each item in the search list
CSearchString *itemP = nil;
LListIterator searchList ( mSearchList, iterate_FromStart );
while ( searchList.Next ( &itemP ) ) // for each item...
{
ThrowIfNil_( itemP );
delete itemP;
}
// empty the list
mSearchList.RemoveItemsAt( mSearchList.GetCount(), arrayIndex_First );
}
// ===========================================================================